#include "Multigrid.h"
using namespace std;

int main(){
    int n,M = 20;
    //M:the number of maximum iteration
    double u0,un,epsilon;
    //u0,un: boundary conditions
    string s,res,inte,cyc;
    //res:restriction operator;inte:interpolation operator;cyc:cycle

    ifstream in1("./test/3.data");
    ofstream out1("./run/3.data");

    epsilon = 1e-8;

    while (!in1.eof()){
        in1 >> n;
        getline(in1,s);
        getline(in1,res);
        getline(in1,inte);
        getline(in1,cyc);
        if(in1.fail()) break;
        
        out1 << "n: " << n <<" res: " <<res <<" inte: " <<inte << " cyc: " << cyc<<"\n";
        
        double h = 1.0/n;
        Multigrid g(n);
        
        double v0[n-1];
        double f0[n-1];
        double u[n-1];
        u0 = 1;
        un = exp(sin(1));
        for(int j = 0;j < n-1;j = j + 1){
            double x = (j+1)*h;
            v0[j] = 0;
            f0[j] = -exp(sin(x))*(-sin(x)+cos(x)*cos(x));
            u[j] = exp(sin(x));
        }
        f0[0] = f0[0] + u0/h/h;
        f0[n-2] = f0[n-2] + un/h/h;
        
        if(res == "injection") g.ISFW = false;
        if(inte == "quadratic") g.ISL = false;
        if(cyc == "full multigrid cycle") g.ISVC = false;
          
        g.solve(v0,f0,u,M,epsilon,out1);
        for(int i = 0;i < 100;i = i + 1)
            out1 << "-";
        out1 << endl;
    }
    in1.close();
    out1.close();

    ifstream in2("./test/4.data");
    ofstream out2("./run/4.data");
    
    while (!in2.eof()){
        in2 >> n >> epsilon;
        if(in1.fail()) break;
    
        out2 << "n: " << n << "  epsilon: " << epsilon << endl;

        double h = 1.0/n;
        Multigrid g(n);
        
        double v0[n-1];
        double f0[n-1];
        double u[n-1];
        u0 = 1;
        un = exp(sin(1));
        for(int j = 0;j < n-1;j = j + 1){
            double x = (j+1)*h;
            v0[j] = 0;
            f0[j] = -exp(sin(x))*(-sin(x)+cos(x)*cos(x));
            u[j] = exp(sin(x));
        }
        f0[0] = f0[0] + u0/h/h;
        f0[n-2] = f0[n-2] + un/h/h;
        
        g.solve(v0,f0,u,M,epsilon,out2);
        for(int i = 0;i < 100;i = i + 1)
            out2 << "-";
        out2 << endl;
    }
    out2.close();
    in2.close();
   
    ifstream in3("./test/3.data");
    ofstream out3("./run/5.data");
    epsilon = 1e-8;
    while (!in3.eof()){
        in3 >> n;
        getline(in3,s);
        getline(in3,res);
        getline(in3,inte);
        getline(in3,cyc);
        if(in3.fail()) break;
        
        out3 << "n: " << n <<" res: " <<res <<" inte: " <<inte << " cyc: " << cyc<<"\n";
        
        double h = 1.0/n;
        Multigrid g(n);
        
        double v0[n-1];
        double f0[n-1];
        double u[n-1];
        u0 = 0;
        un = 0;
        for(int j = 0;j < n-1;j = j + 1){
            double x = (j+1)*h;
            v0[j] = 0;
            f0[j] = -(x*x+3*x)*exp(x);
            u[j] = (x*x-x)*exp(x);
        }
        f0[0] = f0[0] + u0/h/h;
        f0[n-2] = f0[n-2] + un/h/h;
        
        if(res == "injection") g.ISFW = false;
        if(inte == "quadratic") g.ISL = false;
        if(cyc == "full multigrid cycle") g.ISVC = false;
          
        g.solve(v0,f0,u,M,epsilon,out3);
        for(int i = 0;i < 100;i = i + 1)
            out3 << "-";
        out3 << endl;
    }
    in3.close();
    out3.close();
}
